#pragma once

#include "KtCommon/TPumaMT.h"

class IDataSink
{
public:
	IDataSink(){}
	virtual ~IDataSink(){}

public:
	virtual void OnSinkData(PBYTE pbData, DWORD dwDataLen, DWORD dwUserData, LPVOID lpParam)=0;
};

typedef struct{
	
	IDataSink*		pSink;
	DWORD			dwUserData;
}DataSinkItem;

typedef std::list<DataSinkItem> DataSinkList;

class CDataSinkManager
{
public:
	CDataSinkManager(){}
	virtual ~CDataSinkManager(){}

public:
	BOOL AddSink(IDataSink* pSink, DWORD dwUserData)
	{
		m_SinkLock.Lock();
		DataSinkList::iterator i;
		BOOL bFound = FALSE;
		for( i = m_lsSink.begin();i!=m_lsSink.end();i++){
			if( (*i).pSink == pSink ){
				bFound = TRUE;
				break;
			}
		}
		if( !bFound )
		{
			DataSinkItem item;
			item.pSink = pSink;
			item.dwUserData = dwUserData;
			
			m_lsSink.push_back( item );
		}
		m_SinkLock.Unlock();
		
		return TRUE;
	}
	BOOL RemoveSink(IDataSink* pSink )
	{
		m_SinkLock.Lock();
		DataSinkList::iterator i;
		BOOL bFound = FALSE;
		for( i = m_lsSink.begin();i!=m_lsSink.end();i++)
		{
			if( (*i).pSink == pSink )
			{
				m_lsSink.erase( i );
				break;
			}
		}
		m_SinkLock.Unlock();
		return TRUE;
	}

	int GetSinkCount()
	{
		m_SinkLock.Lock();
		int nCount = m_lsSink.size();
		m_SinkLock.Unlock();
		return nCount;
	}

	void ClearSinks()
	{
		m_SinkLock.Lock();
		m_lsSink.clear();
		m_SinkLock.Unlock();
	}

	void ProcessData(PBYTE pbData, DWORD dwDataLen, LPVOID lpParam)
	{
		m_SinkLock.Lock();
		DataSinkList::iterator i;
		for( i = m_lsSink.begin();i!=m_lsSink.end();i++){
			IDataSink *pSink = (*i).pSink;
			pSink->OnSinkData( pbData,dwDataLen,(*i).dwUserData,lpParam );
		}
		m_SinkLock.Unlock();
	}

private:
	TCriticalSection	m_SinkLock;
	DataSinkList		m_lsSink;
};







